home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 359_11 / patch5.000 / GO32_PAGING.C < prev    next >
C/C++ Source or Header  |  1991-09-11  |  17KB  |  692 lines

  1. /* This is file PAGING.C */
  2. /*
  3. ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. **
  5. ** This file is distributed under the terms listed in the document
  6. ** "copying.dj", available from DJ Delorie at the address above.
  7. ** A copy of "copying.dj" should accompany this file; if not, a copy
  8. ** should be available from where this file was obtained.  This file
  9. ** may not be distributed without a verbatim copy of "copying.dj".
  10. **
  11. ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. */
  14.  
  15. /* Modified for VCPI Implement by Y.Shibata Aug 5th 1991 */
  16. /* History:112,12 */
  17.  
  18. #include <dos.h>
  19. #include <fcntl.h>
  20. #include <io.h>
  21. #include <sys/stat.h>
  22.  
  23. #include "build.h"
  24. #include "types.h"
  25. #include "paging.h"
  26. #include "graphics.h"
  27. #include "tss.h"
  28. #include "idt.h"
  29. #include "gdt.h"
  30. #include "valloc.h"
  31. #include "dalloc.h"
  32. #include "utils.h"
  33. #include "aout.h"
  34. #include "mono.h"
  35. #include "vcpi.h"
  36.  
  37. #define VERBOSE 0
  38.  
  39. #if DEBUGGER
  40. #define MAX_PAGING_NUM 1
  41. #else
  42. #define MAX_PAGING_NUM 4
  43. #endif
  44.  
  45. extern word32 ptr2linear(void far *ptr);
  46.  
  47. CLIENT    client;        /*  VCPI Change Mode Structure  */
  48. word32    abs_client;    /*  _DS * 16L + &client        */
  49. far32    vcpi_entry;
  50. SYS_TBL    int_descriptor;
  51. SYS_TBL gbl_descriptor;
  52.  
  53. extern word16 vcpi_installed;    /*  VCPI Installed Flag  */
  54. extern near protect_entry();
  55.  
  56. extern TSS *utils_tss;
  57. extern int debug_mode;
  58. extern word16 mem_avail;
  59. extern int self_contained;
  60. extern long header_offset;
  61.  
  62. typedef struct AREAS {
  63.   word32 first_addr;
  64.   word32 last_addr;
  65.   word32 foffset; /* corresponding to first_addr; -1 = zero fill only */
  66.   } AREAS;
  67.  
  68. #define MAX_AREA    8
  69. static AREAS areas[MAX_AREA];
  70. static char *aname[MAX_AREA] = {
  71.     "text ",
  72.     "data ",
  73.     "bss  ",
  74.     "arena",
  75.     "stack",
  76.     "vga  ",
  77.     "syms ",
  78.     "emu"
  79. };
  80. static char achar[MAX_AREA] = "tdbmsg?e";
  81. typedef enum {
  82.   A_text,
  83.   A_data,
  84.   A_bss,
  85.   A_arena,
  86.   A_stack,
  87.   A_vga,
  88.   A_syms,
  89.   A_emu
  90. } AREA_TYPES;
  91.  
  92. static aout_f;
  93. static emu_f;
  94.  
  95. word32 far *pd = 0;
  96. word32 far *graphics_pt;
  97. extern word32 graphics_pt_lin;
  98. char paging_buffer[4096*MAX_PAGING_NUM];
  99.  
  100. /*  VCPI Get Interface  */
  101. void    link_vcpi(word32 far *dir, word32 far *table)
  102. {
  103.  
  104.   vcpi_entry.selector = g_vcpicode * 8;
  105.   vcpi_entry.offset32 = get_interface(table,&gdt[g_vcpicode]);
  106.   if (vcpi_entry.offset32 == -1L)
  107.     {
  108.     printf("CAUTION !!!!  This EMS driver used address 1B0000H.\n");
  109.     printf("This memory area is broken by handle_screen_swap().\n");
  110.     exit(1);
  111.     }
  112.  
  113.   int_descriptor.limit_16 = sizeof(idt);
  114.   int_descriptor.base_32  = ptr2linear(idt);
  115.   gbl_descriptor.limit_16 = sizeof(gdt);
  116.   gbl_descriptor.base_32  = ptr2linear(gdt);
  117.  
  118.   client.page_table   = (word32)dir>>12;
  119.   client.gdt_address  = ptr2linear(&gbl_descriptor);
  120.   client.idt_address  = ptr2linear(&int_descriptor);
  121.   client.ldt_selector = 0;
  122.   client.tss_selector = g_ctss * 8;
  123.   client.entry_eip    = (word16)protect_entry;
  124.   client.entry_cs     = g_rcode * 8;
  125.  
  126.   abs_client = ptr2linear(&client);
  127. }
  128.  
  129. handle_screen_swap(word32 far *pt)
  130. {
  131.   struct REGPACK r;
  132.   int have_mono=0;
  133.   int have_color=0;
  134.   int have_graphics=0;
  135.   int save, new, i;
  136.  
  137.   r.r_ax = 0x1200;
  138.   r.r_bx = 0xff10;
  139.   r.r_cx = 0xffff;
  140.   intr(0x10, &r);
  141.   if (r.r_cx == 0xffff)
  142.     pokeb(0x40, 0x84, 24); /* the only size for CGA/MDA */
  143.  
  144.   save = peekb(screen_seg, 0);
  145.   pokeb(screen_seg, 0, ~save);
  146.   new = peekb(screen_seg, 0);
  147.   pokeb(screen_seg, 0, save);
  148.   if (new == ~save)
  149.     have_color = 1;
  150.  
  151.   save = peekb(0xb000, 0);
  152.   pokeb(0xb000, 0, ~save);
  153.   new = peekb(0xb000, 0);
  154.   pokeb(0xb000, 0, save);
  155.   if (new == ~save)
  156.     have_mono = 1;
  157.  
  158.   r.r_ax = 0x0f00;
  159.   intr(0x10, &r);
  160.   if ((r.r_ax & 0xff) > 0x07)
  161.     have_graphics = 1;
  162.  
  163.   if (have_graphics && have_mono)
  164.     have_color = 1;
  165.   else if (have_graphics && have_color)
  166.     have_mono = 1;
  167.  
  168.   for (i=0; i<16; i++)
  169.     pt[0x1b0+i] = pt[0xb0+i];
  170.  
  171.   if (have_color && !have_mono)
  172.   {
  173.     for (i=0; i<8; i++)
  174.       pt[0x1b0+i] = pt[0xb8+i];
  175.     return;
  176.   }
  177.   if (have_mono & !have_color)
  178.   {
  179.     for (i=0; i<8; i++)
  180.       pt[0x1b8+i] = pt[0xb0+i];
  181.     return;
  182.   }
  183.  
  184.   if ((biosequip() & 0x0030) == 0x0030) /* mono mode, swap! */
  185.   {
  186.     for (i=0; i<8; i++)
  187.     {
  188.       pt[0x1b0+i] ^= pt[0x1b8+i];
  189.       pt[0x1b8+i] ^= pt[0x1b0+i];
  190.       pt[0x1b0+i] ^= pt[0x1b8+i];
  191.     }
  192.     return;
  193.   }
  194. }
  195.  
  196. paging_set_file(char *fname)
  197. {
  198.   word32 far *pt;
  199.   FILEHDR filehdr;
  200.   AOUTHDR aouthdr;
  201.   SCNHDR scnhdr[3];
  202.   GNU_AOUT gnu_aout;
  203.   int i;
  204.   aout_f = open(fname, O_RDONLY|O_BINARY);
  205.   if (aout_f < 0)
  206.   {
  207.     printf("Can't open file <%s>\n", fname);
  208.     exit(1);
  209.   }
  210.  
  211. #if TOPLINEINFO
  212.   for (i=0; fname[i]; i++)
  213.     poke(screen_seg, i*2+10, fname[i] | 0x0700);
  214. #endif
  215.  
  216.   lseek(aout_f, header_offset, 0);
  217.  
  218.   read(aout_f, &filehdr, sizeof(filehdr));
  219.   if (filehdr.f_magic != 0x14c)
  220.   {
  221.     lseek(aout_f, header_offset, 0);
  222.     read(aout_f, &gnu_aout, sizeof(gnu_aout));
  223.     a_tss.tss_eip = gnu_aout.entry;
  224.     aouthdr.tsize = gnu_aout.tsize;
  225.     aouthdr.dsize = gnu_aout.dsize;
  226.     aouthdr.bsize = gnu_aout.bsize;
  227.   }
  228.   else
  229.   {
  230.     read(aout_f, &aouthdr, sizeof(aouthdr));
  231.     a_tss.tss_eip = aouthdr.entry;
  232.     read(aout_f, scnhdr, sizeof(scnhdr));
  233.   }
  234.   a_tss.tss_cs = g_acode*8;
  235.   a_tss.tss_ds = g_adata*8;
  236.   a_tss.tss_es = g_adata*8;
  237.   a_tss.tss_fs = g_adata*8;
  238.   a_tss.tss_gs = g_adata*8;
  239.   a_tss.tss_ss = g_adata*8;
  240.   a_tss.tss_esp = 0x7ffffffc;
  241.  
  242.   if (filehdr.f_magic == 0x14c)
  243.   {
  244.     areas[0].first_addr = aouthdr.text_start + ARENA;
  245.     areas[0].foffset = scnhdr[0].s_scnptr + header_offset;
  246.     areas[0].last_addr = areas[0].first_addr + aouthdr.tsize;
  247.   }
  248.   else if (filehdr.f_magic == 0x10b)
  249.   {
  250.     areas[0].first_addr = ARENA;
  251.     if (a_tss.tss_eip >= 0x1000)    /* leave space for null reference */
  252.       areas[0].first_addr += 0x1000;    /* to cause seg fault */
  253.     areas[0].foffset = header_offset;
  254.     areas[0].last_addr = areas[0].first_addr + aouthdr.tsize + 0x20;
  255.   }
  256. #if DEBUGGER
  257.   else if (filehdr.f_magic == 0x107)
  258.   {
  259.     struct stat sbuf;
  260.     fstat(aout_f, &sbuf);
  261.     areas[0].first_addr = ARENA;
  262.     areas[0].foffset = 0x20 + header_offset;
  263.     areas[0].last_addr = sbuf.st_size + ARENA - 0x20;
  264.   }
  265.   else
  266.   {
  267.     struct stat sbuf;
  268.     fstat(aout_f, &sbuf);
  269.     areas[0].first_addr = ARENA;
  270.     areas[0].foffset = header_offset;
  271.     areas[0].last_addr = sbuf.st_size + ARENA;
  272.   }
  273. #else
  274.   else
  275.   {
  276.     printf("Unknown file type 0x%x (0%o)\n", filehdr.f_magic, filehdr.f_magic);
  277.     exit(-1);
  278.   }
  279. #endif
  280. #if DEBUGGER
  281.   if (debug_mode)
  282.     printf("%ld+", aouthdr.tsize);
  283. #endif
  284.  
  285.   if (filehdr.f_magic == 0x14c)
  286.   {
  287.     areas[1].first_addr = aouthdr.data_start + ARENA;
  288.     areas[1].foffset = scnhdr[1].s_scnptr + header_offset;
  289.   }
  290.   else
  291.   {
  292.     areas[1].first_addr = (areas[0].last_addr+0x3fffffL)&~0x3fffffL;
  293.     areas[1].foffset = ((aouthdr.tsize + 0x20 + 0xfffL) & ~0xfffL) + header_offset;
  294.   }
  295.   areas[1].last_addr = areas[1].first_addr + aouthdr.dsize - 1;
  296. #if DEBUGGER
  297.   if (debug_mode)
  298.     printf("%ld+", aouthdr.dsize);
  299. #endif
  300.  
  301.   areas[2].first_addr = areas[1].last_addr + 1;
  302.   areas[2].foffset = -1;
  303.   areas[2].last_addr = areas[2].first_addr + aouthdr.bsize - 1;
  304. #if DEBUGGER
  305.   if (debug_mode)
  306.     printf("%ld = %ld\n", aouthdr.bsize,
  307.       aouthdr.tsize+aouthdr.dsize+aouthdr.bsize);
  308. #endif
  309.  
  310.   areas[3].first_addr = areas[2].last_addr;
  311.   areas[3].last_addr = areas[3].first_addr;
  312.   areas[3].foffset = -1;
  313.  
  314.   areas[4].first_addr = 0x50000000;
  315.   areas[4].last_addr = 0x8fffffff;
  316.   areas[4].foffset = -1;
  317.  
  318.   areas[5].first_addr = 0xe0000000;
  319.   areas[5].last_addr = 0xe03fffff;
  320.   areas[5].foffset = -1;
  321.  
  322.   areas[A_syms].first_addr = 0xa0000000;
  323.   areas[A_syms].last_addr = 0xafffffff;
  324.   areas[A_syms].foffset = -1;
  325.  
  326.   pd = (word32 far *)((long)valloc(VA_640) << 24);
  327.   pt = (word32 far *)((long)valloc(VA_640) << 24);
  328.   for (i=0; i<1024; i++)
  329.     pd[i] = 0;
  330.  
  331.   if (vcpi_installed)
  332.     {
  333.     link_vcpi(pd,pt);        /*  Ge